import os
import sys
import time
import getpass


dir_path = os.path.dirname(__file__)
deadline_path=os.path.join(dir_path,'Deadline')
print(deadline_path)
sys.path.append(deadline_path)

if sys.version>'3':
    from PySide2.QtGui import *
    from PySide2.QtCore import *
    from PySide2.QtWidgets import *
else:
    from PySide2.QtGui import *
    from PySide2.QtCore import *
    from PySide2.QtWidgets import *
import CONFIG as cfg


deadline = cfg.MZ_CONFIG.get('deadline', {})


try:
    import nuke
    import DeadlineConnect as Connect
except Exception as DeadlineConnect_ERR:
    print('DeadlineConnect_ERR:', str(DeadlineConnect_ERR))



class WriteNodeListWiget(QWidget):
    node_names_Signal =Signal(str)

    def __init__(self):
        super(WriteNodeListWiget, self).__init__()
        self.main_layout = QVBoxLayout()
        self.wl = WriteNodeList()
        self.btn = QPushButton('OK')
        self.btn.setMinimumHeight(35)
        self.btn.clicked.connect(self._choose_writes)
        self.main_layout.addWidget(self.wl)
        self.main_layout.addWidget(self.btn)
        self.setLayout(self.main_layout)

    def _choose_writes(self):
        node_names = ''
        sn = self.wl.selectedItems()
        if sn:
            node_name_list = []
            for i in sn:
                node_name = i.text()
                node_name_list.append(node_name)
            node_names = ','.join(node_name_list)

        self.node_names_Signal.emit(node_names)
        self.close()

class WriteNodeList(QListWidget):

    # nodename_Signal=Signal(str)
    def __init__(self):
        super(WriteNodeList, self).__init__()
        self.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.setWindowTitle(u'Choose')
        # self.doubleClicked.connect(self._choose_write)

    def _choose_write(self,index):
        item=self.itemFromIndex(index)


        text=item.text()


        self.nodename_Signal.emit(text)
        self.close()

    def init_items(self,write_list):
        if write_list:
            self.clear()
            for i in write_list:
                item=QListWidgetItem()
                item.setText(i.name())
                item.setTextAlignment(Qt.AlignCenter)
                self.addItem(item)



class DeadlineWindow(QDialog):

    def __init__(self, data={}):
        super(DeadlineWindow, self).__init__()
        self.data = data
        self.priority = 89
        self.write_node_map = {}
        self.connectionObject = Connect.DeadlineCon(deadline['web_serive'], deadline['port'])

        self.setWindowTitle('Submit Job')
        self.setMinimumHeight(350)

        self.mid_font = QFont('', 20, 65)

        self.main_layout = QVBoxLayout()
        self.main_layout.setAlignment(Qt.AlignTop)
        self.main_layout.setSpacing(25)
        self.mid_text = QLabel('Deadline Job')
        self.mid_text.setFont(self.mid_font)
        self.mid_text.setAlignment(Qt.AlignCenter)
        self.job_name_layout = QHBoxLayout()
        self.job_name_label = QLabel('Job Name:')
        self.job_name_edit = QLineEdit()
        self.job_name_edit.setText(self.data.get('job_name',''))
        self.job_name_layout.addWidget(self.job_name_label)
        self.job_name_layout.addWidget(self.job_name_edit)
        self.node_layout = QHBoxLayout()
        self.node_label = QLabel('Node:')
        self.node_edit = QLineEdit()
        self.node_edit.setText(self.data.get('writer',''))
        self.node_choose_btn = QPushButton('Choose')
        self.node_choose_btn.clicked.connect(self._choose_write_node)
        self.node_layout.addWidget(self.node_label)
        self.node_layout.addWidget(self.node_edit)
        self.node_layout.addWidget(self.node_choose_btn)
        self.export_type_layout = QHBoxLayout()
        self.export_mov_radio = QRadioButton('mov')
        self.export_mov_radio.setChecked(Qt.Checked)
        self.export_mov_radio.clicked.connect(self._change_type)

        self.export_exr_radio = QRadioButton('exr')
        self.export_exr_radio.clicked.connect(self._change_type)
        self.export_type_layout.addWidget(self.export_mov_radio)
        self.export_type_layout.addWidget(self.export_exr_radio)
        self.chunkSize_layout = QHBoxLayout()
        self.chunkSize_label = QLabel('Frames Per Task:')
        self.chunkSize_edit = QLineEdit('10')
        rex = QRegExp("[0-9\.]+$")
        rv = QRegExpValidator(rex, self)
        self.chunkSize_edit.setValidator(rv)
        self.chunkSize_edit.setEnabled(False)
        self.chunkSize_layout.addWidget(self.chunkSize_label)
        self.chunkSize_layout.addWidget(self.chunkSize_edit)

        self.frame_layout = QHBoxLayout()
        self.frame_layout.setContentsMargins(0, 0, 140, 0)
        self.frame_label = QLabel('Frames:')
        self.frame_start_edit = QLineEdit()
        self.frame_start_edit.setText(self.data.get('start','0'))
        self.frame_start_edit.setFixedWidth(35)
        self.frame_end_edit = QLineEdit()
        self.frame_end_edit.setText(self.data.get('end', '0'))
        self.frame_end_edit.setFixedWidth(35)
        self.frame_layout.addWidget(self.frame_label)
        self.frame_layout.addWidget(self.frame_start_edit)
        self.frame_layout.addWidget(self.frame_end_edit)
        self.init_frames()
        self.pool_layout = QHBoxLayout()
        self.pool_layout.setContentsMargins(0, 0, 150, 0)
        self.pool_label = QLabel('Pool:')
        self.pool_menu = QComboBox()
        self.init_pools()
        self.pool_layout.addWidget(self.pool_label)
        self.pool_layout.addWidget(self.pool_menu)
        # self.chunk_layout = QHBoxLayout()
        # self.chunk_layout.setContentsMargins(0, 0, 150, 0)
        # self.chunk_label = QLabel('Frame Per Task:')
        # self.chunk_edit = QLineEdit()
        # self.chunk_edit.setText('9999')
        # self.chunk_edit.setFixedWidth(30)
        # self.chunk_layout.addWidget(self.chunk_label)
        # self.chunk_layout.addWidget(self.chunk_edit)
        # self.priority_layout = QHBoxLayout()
        # self.priority_label = QLabel('Priority:')
        # self.priority_edit = QLineEdit()
        # self.priority_edit.setFixedWidth(30)
        # self.priority_edit.setText('50')
        # self.priority_slider = QSlider(Qt.Horizontal)
        # self.priority_slider.setMaximum(100)
        # self.priority_slider.setValue(50)
        # self.priority_slider.valueChanged.connect(self._change_priority)
        # self.priority_layout.addWidget(self.priority_label)
        # self.priority_layout.addWidget(self.priority_edit)
        # self.priority_layout.addWidget(self.priority_slider)
        self.btn_layout = QHBoxLayout()
        self.btn_layout.setContentsMargins(0, 20, 0, 0)
        self.OK_btn = QPushButton('Submit')
        self.OK_btn.clicked.connect(self._submit)
        self.NO_btn = QPushButton('Cancel')
        self.NO_btn.clicked.connect(self._cancel)
        self.btn_layout.addWidget(self.OK_btn)
        self.btn_layout.addWidget(self.NO_btn)

        self.main_layout.addWidget(self.mid_text)
        self.main_layout.addLayout(self.job_name_layout)
        self.main_layout.addLayout(self.node_layout)
        self.main_layout.addLayout(self.export_type_layout)
        self.main_layout.addLayout(self.chunkSize_layout)
        self.main_layout.addLayout(self.frame_layout)
        self.main_layout.addLayout(self.pool_layout)
        # self.main_layout.addLayout(self.chunk_layout)
        # self.main_layout.addLayout(self.priority_layout)
        self.main_layout.addLayout(self.btn_layout)
        self.setLayout(self.main_layout)

    def init_frames(self):
        start_frame = int(nuke.root()['first_frame'].value())
        end_frame = int(nuke.root()['last_frame'].value())
        self.frame_start_edit.setText(str(start_frame))
        self.frame_end_edit.setText(str(end_frame))


    def init_pools(self):
        if deadline:
            # print(deadline)
            pools = deadline.get('pools',['Disconnected'])
            if '64' in pools:
                # self.pool_menu.addItems(pools)
                self.pool_menu.addItems(['64'])
            else:
                self.pool_menu.addItems(['Disconnected'])
        else:
            self.pool_menu.addItems(['Disconnected'])

    def _change_priority(self,value):
        self.priority = value
        self.priority_edit.setText(str(value))


    def _choose_write_node(self):
        sn = nuke.selectedNodes()
        writes = []
        for i in sn:
            if i.Class() == 'Write':
                writes.append(i)
                write_name = i.name()
                self.write_node_map[write_name] = i
                # print('has')
        if not writes:
            for n in nuke.allNodes():
                if n.Class() == 'Write':
                    writes.append(n)
                    write_name = n.name()
                    self.write_node_map[write_name] = n
        self.writes_list_window = WriteNodeListWiget()
        self.writes_list_window.node_names_Signal.connect(self._set_write)
        self.writes_list_window.wl.init_items(writes)
        self.writes_list_window.show()



    def _set_write(self,write_name):
        print(write_name)
        write_node = self.write_node_map.get(write_name,None)
        if write_node:
            write_node.setSelected(True)
            write_node.showControlPanel()
        self.node_edit.setText(write_name)


    def _change_type(self):
        # print(status)
        status = self.export_exr_radio.isChecked()
        if status:  # export_exr
            self.chunkSize_label.setEnabled(True)
            self.chunkSize_edit.setEnabled(True)
            self._change2exr(True)
        else:
            self.chunkSize_label.setEnabled(False)
            self.chunkSize_edit.setEnabled(False)
            self._change2exr(False)

    def _change2exr(self,toExr):
        node_name = self.node_edit.text()
        try:
            write = nuke.toNode(node_name)
            f = write['file'].value()
            if toExr:
                path = f.replace('.mov', '.%04d.exr')
                write['file'].fromUserText(path)
                write['channels'].setValue('all')
            else:
                path = f.replace('.%04d.exr', '.mov').replace('.%03d.exr', '.mov').replace('.%02d.exr', '.mov')
                write['file'].fromUserText(path)
                # write['meta_codec'].setValue('avc1')
                n = nuke.Root()
                fps = n['fps'].value()
                # print(fps)
                try:
                    write['mov64_fps'].setValue(fps)
                except :
                    pass
                try:
                    write['meta_codec'].setValue('avc1')
                except :
                    pass
                try:
                    write['mov64_codec'].setValue('h264')
                except :
                    pass

        except Exception as _change2exr_ERR:
            print('_change2exr_ERR:',_change2exr_ERR)


    def get_version(self):

        return '.'.join([str(nuke.NUKE_VERSION_MAJOR),str(nuke.NUKE_VERSION_MINOR)])#,str(nuke.NUKE_VERSION_RELEASE)


    def create_dirs(self):
        """
        create all director from all Write file path
        """
        if self.write_node_map:
            for n in self.write_node_map.values():
                file_path = n['file'].value()
                dir_path = os.path.dirname(file_path)
                if not os.path.exists(dir_path):
                    os.makedirs(dir_path)


    def _copy_deadline_nk(self):
        root = nuke.root()['name'].value()
        root_dir,nuke_file = os.path.split(root)
        nuke_name,_nk = os.path.splitext(nuke_file)

        nk_deadline_dir = os.path.join(root_dir,'nk_deadline')
        if not os.path.exists(nk_deadline_dir):
            os.makedirs(nk_deadline_dir)
        submit_time = time.strftime('%Y-%m-%d__%H-%M-%S')

        new_nk_file = nuke_name+'_'+submit_time+_nk
        new_path = os.path.join(nk_deadline_dir,new_nk_file)
        print('new_path:',new_path)

        nuke.scriptSave(new_path)
        return new_path

    def _create_dir(self):
        """
        create write output directory
        """
        writer_name = self.node_edit.text()
        writer_node = nuke.toNode(writer_name)
        file_path = writer_node['file'].value()
        file_dir = os.path.dirname(file_path)
        if not os.path.exists(file_dir):
            os.makedirs(file_dir)

    def _submit(self):
        # result = QMessageBox.question(self, 'Tips', 'Save Before Submit ', QMessageBox.Yes | QMessageBox.No,
        #                               QMessageBox.No)
        # if result == QMessageBox.Yes:
        #     nuke.scriptSave("")
        # else:
        #     pass

        pool = self.pool_menu.currentText()
        if self.job_name_edit.text() and self.node_edit.text() and pool=='64':
            self._create_dir()
            deadline_nk_path = self._copy_deadline_nk()
            # self.create_dirs()

            chunk = int(self.chunkSize_edit.text()) if self.export_exr_radio.isChecked() else 9999
            # job_data = {"Name":self.job_name_edit.text()+'_'+getpass.getuser(),
            job_data = {"Name":self.job_name_edit.text(),
            'UserName':getpass.getuser(),
            'Frames':'{}-{}'.format(self.frame_start_edit.text(),self.frame_end_edit.text()),
            # 'ChunkSize':int(self.chunk_edit.text()),
            'Pool' : pool,
            'ChunkSize':chunk,
            'Priority': self.priority,
            'Plugin':'Nuke'}
            # 'OutputFilename0':out_path }

            version = self.get_version()

            plugin_data = {'NukeX':False,
            'WriteNode': self.node_edit.text(),
            'Version':version,
            'EnforceRenderOrder':True,
            'SceneFile':deadline_nk_path}
            # 'SceneFile':nuke.root()['name'].value()}
            try:
                job = self.connectionObject.Jobs.SubmitJob(job_data, plugin_data)
                job_id = job['_id']
                QMessageBox.information(None,'Tips','Submit')
            except Exception as submit_ERR:
                print('submit_ERR:',str(submit_ERR))
                QMessageBox.information(None, 'Tips', 'Failed')
        else:
            QMessageBox.information(None,'Erro','Failed')


    def _cancel(self):
        self.close()



if __name__ == '__main__':
    app=QApplication(sys.argv)
    d=DeadlineWindow()
    d.show()
    sys.exit(app.exec_())